<?php

/**
 * This file is part of easyCMS.
 *
 * (c) 2023 easyCMS <easyCMS@easycms.net.cn>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace app\admin\controller;

use app\admin\model\BaseModel;
use app\admin\model\SystemAdminRole;
use app\admin\model\SystemMenu;
use app\admin\model\SystemRole;
use app\admin\model\SystemRoleRight;
use app\admin\validate\RoleValidate;
use Exception;
use support\Db;
use support\Request;

class RoleController
{
    /**
     * 角色列表
     */
    #[permits('admin:role:list')]
    public function index(Request $request): \support\Response
    {
        return view('role/roleList');
    }

    /**
     * 角色列表
     */
    #[permits('admin:role:list')]
    public function roleListData(Request $request): \support\Response
    {
        $admin = admin();
        $roles = SystemRole::where('status', BaseModel::STATUS_NORMAL)->orderBy('id', 'ASC')->get()->toArray();

        return json(['code' => 0, 'msg' => '', 'count' => 0, 'data' => $roles]);
    }

    /**
     * 角色新增
     */
    #[permits('admin:role:add')]
    public function roleAdd(Request $request): \support\Response
    {
        $data['role'] = new SystemRole();
        $menuAll      = SystemMenu::where('status', BaseModel::STATUS_NORMAL)->orderBy('sort', 'ASC')->get()->toArray();
        array_unshift($menuAll, ['id' => 0, 'title' => '根菜单', 'pid' => -1, 'level' => 0]);
        $data['menuAll']  = $this->getTree($menuAll, -1);
        $data['hasMenus'] = '';

        return view('role/roleEdit', $data);
    }

    /**
     * 角色新增
     */
    #[permits('admin:role:add')]
    public function doRoleAdd(Request $request): \support\Response
    {
        $code = 0;
        $msg  = '';

        $postData = [
            'name'  => $request->post('name'),
            'menus' => $request->post('menus'),
        ];

        $validate = new RoleValidate();
        if ($validate->check($postData)) {
            $role         = new SystemRole();
            $role->name   = $postData['name'];
            $role->status = BaseModel::STATUS_NORMAL;

            Db::beginTransaction();

            try {
                // 保存菜单信息
                $role->save();
                // 增加关联关系
                $role->menus()->attach(explode(',', $postData['menus']));

                Db::commit();
                $msg = '增加成功';
            } catch (Exception $e) {
                Db::rollBack();
                $code = 1;
                $msg  = '增加失败';
            }
        } else {
            $code = 1;
            $msg  = $validate->getError();
        }

        return json(['code' => $code, 'msg' => $msg]);
    }

    /**
     * 角色修改
     */
    #[permits('admin:role:edit')]
    public function roleEdit(Request $request): \support\Response
    {
        $id           = $request->get('id');
        $data['role'] = SystemRole::find($id);
        $menuAll      = SystemMenu::where('status', BaseModel::STATUS_NORMAL)->orderBy('sort', 'ASC')->get()->toArray();
        array_unshift($menuAll, ['id' => 0, 'title' => '根菜单', 'pid' => -1, 'level' => 0]);
        $data['menuAll'] = $this->getTree($menuAll, -1);
        $hasMenusArr     = $data['role']->menus()->get()->toArray();
        $hasMenus        = '';

        foreach ($hasMenusArr as $m) {
            $hasMenus .= $m['id'] . ',';
        }
        $data['hasMenus'] = $hasMenus;

        return view('role/roleEdit', $data);
    }

    /**
     * 角色修改
     */
    #[permits('admin:role:edit')]
    public function doRoleEdit(Request $request): \support\Response
    {
        $code = 0;
        $msg  = '';

        $postData = [
            'id'    => $request->post('id'),
            'name'  => $request->post('name'),
            'menus' => $request->post('menus'),
        ];

        $validate = new RoleValidate();
        if ($validate->check($postData)) {
            $role = SystemRole::find($postData['id']);
            if ($role !== null && $role->id > 0) {
                if ($role->id === 1) {
                    $code = 1;
                    $msg  = '超管不能修改';
                } else {
                    $role->name = $postData['name'];

                    Db::beginTransaction();

                    try {
                        // 删除原有的关联关系
                        SystemRoleRight::where('role_id', $role->id)->delete();
                        // 增加关联关系
                        $role->menus()->attach(explode(',', $postData['menus']));
                        // 保存菜单信息
                        $role->update();
                        Db::commit();
                        $msg = '修改成功';
                    } catch (Exception $e) {
                        Db::rollBack();
                        $code = 1;
                        $msg  = '修改失败';
                    }
                }
            } else {
                $code = 1;
                $msg  = '该角色不存在';
            }
        } else {
            $code = 1;
            $msg  = $validate->getError();
        }

        return json(['code' => $code, 'msg' => $msg]);
    }

    /**
     * 角色删除
     */
    #[permits('admin:role:delete')]
    public function roleDelete(Request $request): \support\Response
    {
        $code = 0;
        $msg  = '';
        $id   = $request->post('id');

        if ((int) $id === 1) {
            $code = 1;
            $msg  = '不能删除超级管理员角色';
        } else {
            $count = SystemAdminRole::where('role_id', $id)->count();
            if ($count > 0) {
                $code = 1;
                $msg  = '该角色下还有用户，不能删除';
            } else {
                $role = SystemRole::find($id);
                if ($role !== null && $role->id > 0) {
                    if ($role->delete()) {
                        $msg = '删除成功';
                    } else {
                        $msg = '删除失败';
                    }
                }
            }
        }

        return json(['code' => $code, 'msg' => $msg]);
    }

    /**
     * 数组转换为treeTable结构
     */
    private function getTree(mixed $data, mixed $pid): array
    {
        $list = [];

        foreach ($data as $k => $v) {
            if ((int) ($v['pid']) === $pid) {
                $ss['title']    = $v['title']; // 这里可以加个层级次数
                $ss['value']    = $v['id'];
                $ss['level']    = $v['level'];
                $ss['children'] = self::getTree($data, (int) ($v['id']));
                if ($ss['children'] === null) {
                    unset($ss['children']);
                }
                $list[] = $ss;
            }
        }

        return $list;
    }
}
